package com.shockweb.common.log;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Timestamp;
import org.apache.log4j.Logger;

import com.shockweb.common.utils.DataFormat;
import com.shockweb.common.context.ContextManager;
/**
 *
 * 自定义日志级别，提供静态方法选择级别日志记录器；基于log4j
 * @author: 彭明华
 * 2017年5月15日 下午2:44:43
 *
 */
public class LogManager {

	/**
	 * 日志起始标志
	 */
    public static final String START = "[start]";
    
    /**
     * 日志结束标志
     */
    public static final String END = "[end]";
    
    /**
     * 记录调试日志
     * @param clazz 信息对象类
     * @param message 信息
     */
    public static void infoLog(Class<?> clazz,String message){
        Logger.getLogger(clazz).info(START + message + END);
    }

    /**
     * 记录调试日志
     * @param clazz 信息对象类
     * @param message 信息
     */
    public static void infoLog(Class<?> clazz,StringBuilder message){
    	message.insert(0, START);
    	message.append(END);
        Logger.getLogger(clazz).info(message.toString());
    }
    
    /**
     * 代码中信息日志
     * @param clazz
     * @param ex
     */
    public static void errorLog(Class<?> clazz,Throwable ex){
    	StringBuilder log = new StringBuilder(START);
    	log.append("{\"state\":\"error\"");
    	log.append(",\"requestId\":\"").append(ContextManager.getUuid()).append("\"");
    	log.append(",\"step\":\"").append(ContextManager.getStep()).append("\"");
    	if(ContextManager.getOwner()!=null){
    		log.append(",\"owner\":\"").append(ContextManager.getOwner()).append("\"");
    	}
		log.append(",\"time\":\"").append(DataFormat.format(new Timestamp(System.currentTimeMillis()))).append("\"");
		log.append(",\"error\":\"").append(exceptionToString(ex).replaceAll("\"", "\"\"")).append("\"}");
		log.append(END);
        Logger.getLogger(clazz).error(log.toString());
    }
 
    /**
     * 获取exception的完整信息
     * @param ex
     * @return
     */
    public static String exceptionToString(Throwable ex){
		StringWriter sw = null;
		PrintWriter pw = null;
		try{
			sw = new StringWriter();
			pw = new PrintWriter(sw, true); 
			ex.printStackTrace(pw);
			return sw.toString();
		}finally{
			try {
				if(pw!=null)
					pw.close();
			} catch (Exception e) {
			}
			try {
				if(sw!=null)
					sw.close();
			} catch (Exception e) {
			}
		}
    }
    

    
    /**
     * 代码中警告的日志
     * @param clazz
     * @param message
     * @param ex
     */
    public static void warnLog(Class<?> clazz,Object message,Throwable ex){
    	StringBuilder log = new StringBuilder(START);
    	log.append("{\"state\":\"warn\"");
    	log.append(",\"requestId\":\"").append(ContextManager.getUuid()).append("\"");
    	log.append(",\"step\":\"").append(ContextManager.getStep()).append("\"");
    	if(ContextManager.getOwner()!=null){
    		log.append(",\"owner\":\"").append(ContextManager.getOwner()).append("\"");
    	}
		log.append(",\"time\":\"").append(DataFormat.format(new Timestamp(System.currentTimeMillis()))).append("\"");
		log.append(",\"message\":\"").append(message.toString().replaceAll("\"", "\"\"")).append("\"");
		if(ex!=null){
			log.append(",\"error\":\"").append(exceptionToString(ex).replaceAll("\"", "\"\"")).append("\"}");
		}else{
			log.append("}");
		}
		log.append(END);
        Logger.getLogger(clazz).warn(log.toString());
    }
    
    /**
     * 代码中错误的日志
     * @param clazz
     * @param message
     * @param ex
     */
    public static void errorLog(Class<?> clazz,String message,Throwable ex){
    	StringBuilder log = new StringBuilder(START);
    	log.append("{\"state\":\"error\"");
    	log.append(",\"requestId\":\"").append(ContextManager.getUuid()).append("\"");
    	log.append(",\"step\":\"").append(ContextManager.getStep()).append("\"");
    	if(ContextManager.getOwner()!=null){
    		log.append(",\"owner\":\"").append(ContextManager.getOwner()).append("\"");
    	}
		log.append(",\"time\":\"").append(DataFormat.format(new Timestamp(System.currentTimeMillis()))).append("\"");
		log.append(",\"message\":\"").append(message.toString().replaceAll("\"", "\"\"")).append("\"");
		if(ex!=null){
			log.append(",\"error\":\"").append(exceptionToString(ex).replaceAll("\"", "\"\"")).append("\"}");
		}else{
			log.append("}");
		}
		log.append(END);
        Logger.getLogger(clazz).warn(log.toString());
    }
    
    /**
     * 代码中警告的日志
     * @param clazz
     * @param message
     */
    public static void warn(Class<?> clazz,Object message){
    	warnLog(clazz,message,null);
    }
    
    /**
     * 代码中调试的日志
     * @param clazz
     * @param message
     */
    public static void debug(Class<?> clazz,Object message){
    	StringBuilder log = new StringBuilder(START);
    	log.append("{\"state\":\"debug\"");
    	log.append(",\"requestId\":\"").append(ContextManager.getUuid()).append("\"");
    	log.append(",\"step\":\"").append(ContextManager.getStep()).append("\"");
    	if(ContextManager.getOwner()!=null){
    		log.append(",\"owner\":\"").append(ContextManager.getOwner()).append("\"");
    	}
		log.append(",\"time\":\"").append(DataFormat.format(new Timestamp(System.currentTimeMillis()))).append("\"");
		log.append(",\"message\":\"").append(message.toString().replaceAll("\"", "\"\"")).append("\"}");
		log.append(END);
        Logger.getLogger(clazz).debug(log.toString());
    }

  
    /**
     * 记录操作信息
     * @param clazz
     * @param operation
     */
    public static void start(Class<?> clazz , String operation){
    	StringBuilder log = new StringBuilder(START);
    	log.append("{\"state\":\"start\"");
    	log.append(",\"requestId\":\"").append(ContextManager.getUuid()).append("\"");
    	log.append(",\"step\":\"").append(ContextManager.getStep()).append("\"");
    	if(ContextManager.getOwner()!=null){
    		log.append(",\"owner\":\"").append(ContextManager.getOwner()).append("\"");
    	}
		log.append(",\"time\":\"").append(DataFormat.format(new Timestamp(System.currentTimeMillis()))).append("\"");
		log.append(",\"operation\":\"").append(operation.replaceAll("\"", "\"\"")).append("\"}");
		log.append(END);
        Logger.getLogger(clazz).info(log.toString());
    }
    
    /**
     * 记录操作信息
     * @param clazz
     * @param millis
     * @param operation
     */
    public static void end(Class<?> clazz ,long millis,String operation){
    	StringBuilder log = new StringBuilder(START);
    	log.append("{\"state\":\"end\"");
    	log.append(",\"requestId\":\"").append(ContextManager.getUuid()).append("\"");
    	log.append(",\"step\":\"").append(ContextManager.getStep()).append("\"");
    	if(ContextManager.getOwner()!=null){
    		log.append(",\"owner\":\"").append(ContextManager.getOwner()).append("\"");
    	}
		log.append(",\"time\":\"").append(DataFormat.format(new Timestamp(System.currentTimeMillis()))).append("\"");
		log.append(",\"millis\":\"").append(DataFormat.format(new Timestamp(millis))).append("\"");
		log.append(",\"operation\":\"").append(operation.replaceAll("\"", "\"\"")).append("\"}");
		log.append(END);
        Logger.getLogger(clazz).info(log.toString());
    }
    
    /**
     * 记录操作信息
     * @param clazz
     * @param millis
     * @param operation
     * @param params
     * @param ex
     */
    public static void error(Class<?> clazz,long millis , String operation , Object[] params , Throwable ex){
    	StringBuilder log = new StringBuilder(START);
    	log.append("{\"state\":\"error\"");
    	log.append(",\"requestId\":\"").append(ContextManager.getUuid()).append("\"");
    	log.append(",\"step\":\"").append(ContextManager.getStep()).append("\"");
    	if(ContextManager.getOwner()!=null){
    		log.append(",\"owner\":\"").append(ContextManager.getOwner()).append("\"");
    	}
		log.append(",\"time\":\"").append(DataFormat.format(new Timestamp(System.currentTimeMillis()))).append("\"");
		log.append(",\"millis\":\"").append(DataFormat.format(new Timestamp(millis))).append("\"");
		log.append(operation).append(",\"params\":[\"");
	        if(params!=null){
	            for (int i = 0; i < params.length; i++) { // 格式化异常栈信息
	            	if(params[i]!=null){
		            	if(i==0){
		            		log.append("\"").append(params[i].toString().replaceAll("\"","\"\"")).append("\"");
		            	}else{
		            		log.append(",\"").append(params[i].toString().replaceAll("\"","\"\"")).append("\"");
		            	}
	            	}else{
		            	if(i==0){
		            		log.append("null");
		            	}else{
		            		log.append(",null");
		            	}
	            	}
	            }
	        }
		log.append("\"]");//.append(ex.getMessage());
		if(ex!=null){
			log.append(",\"error\":\"").append(exceptionToString(ex).replaceAll("\"", "\"\"")).append("\"}");
		}else{
			log.append("}");
		}
        log.append(END);
        Logger.getLogger(clazz).info(log.toString());
    }

} 
